Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AMDGPU] Copy Defs and Uses from Pseudo to Real Instructions #93004

Merged
merged 1 commit into from
May 31, 2024

Conversation

ritter-x2a
Copy link
Member

Currently, the tablegen files that generate the instruction definitions in lib/Target/AMDGPU/AMDGPUGenInstrInfo.inc often only include implicit operands for the architecture-independent pseudo instructions, but not for the corresponding real instructions. The missing implicit operands (most prominently: the EXEC mask) do not affect code generation, since that operates on pseudo instructions, but they are problematic when working with real instructions, e.g., as a decoding result from the MC layer.

This patch copies the implicit Defs and Uses from pseudo instructions to the corresponding real instructions, so that implicit operands are also defined for real instructions.

Addresses issue #89830.

Currently, the tablegen files that generate the instruction definitions
in lib/Target/AMDGPU/AMDGPUGenInstrInfo.inc often only include implicit
operands for the architecture-independent pseudo instructions, but not
for the corresponding real instructions. The missing implicit operands
(most prominently: the EXEC mask) do not affect code generation, since
that operates on pseudo instructions, but they are problematic when
working with real instructions, e.g., as a decoding result from the MC
layer.

This patch copies the implicit Defs and Uses from pseudo instructions to
the corresponding real instructions, so that implicit operands are also
defined for real instructions.

Addresses issue llvm#89830.
@llvmbot
Copy link
Collaborator

llvmbot commented May 22, 2024

@llvm/pr-subscribers-backend-amdgpu

Author: Fabian Ritter (ritter-x2a)

Changes

Currently, the tablegen files that generate the instruction definitions in lib/Target/AMDGPU/AMDGPUGenInstrInfo.inc often only include implicit operands for the architecture-independent pseudo instructions, but not for the corresponding real instructions. The missing implicit operands (most prominently: the EXEC mask) do not affect code generation, since that operates on pseudo instructions, but they are problematic when working with real instructions, e.g., as a decoding result from the MC layer.

This patch copies the implicit Defs and Uses from pseudo instructions to the corresponding real instructions, so that implicit operands are also defined for real instructions.

Addresses issue #89830.


Full diff: https://github.com/llvm/llvm-project/pull/93004.diff

6 Files Affected:

  • (modified) llvm/lib/Target/AMDGPU/BUFInstructions.td (+6)
  • (modified) llvm/lib/Target/AMDGPU/DSInstructions.td (+2)
  • (modified) llvm/lib/Target/AMDGPU/FLATInstructions.td (+4)
  • (modified) llvm/lib/Target/AMDGPU/SMInstructions.td (+2)
  • (modified) llvm/lib/Target/AMDGPU/SOPInstructions.td (+10)
  • (modified) llvm/lib/Target/AMDGPU/VOPInstructions.td (+6)
diff --git a/llvm/lib/Target/AMDGPU/BUFInstructions.td b/llvm/lib/Target/AMDGPU/BUFInstructions.td
index 8eaa113ac1816..f419f0b17352f 100644
--- a/llvm/lib/Target/AMDGPU/BUFInstructions.td
+++ b/llvm/lib/Target/AMDGPU/BUFInstructions.td
@@ -137,6 +137,8 @@ class MTBUF_Real <MTBUF_Pseudo ps, string real_name = ps.Mnemonic> :
   let mayStore           = ps.mayStore;
   let IsAtomicRet        = ps.IsAtomicRet;
   let IsAtomicNoRet      = ps.IsAtomicNoRet;
+  let Uses               = ps.Uses;
+  let Defs               = ps.Defs;
 
   bits<12> offset;
   bits<5>  cpol;
@@ -351,6 +353,8 @@ class MUBUF_Real <MUBUF_Pseudo ps, string real_name = ps.Mnemonic> :
   let IsAtomicNoRet        = ps.IsAtomicNoRet;
   let VALU                 = ps.VALU;
   let LGKM_CNT             = ps.LGKM_CNT;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   bits<12> offset;
   bits<5>  cpol;
@@ -2392,6 +2396,8 @@ class VBUFFER_Real <bits<8> op, BUF_Pseudo ps, string real_name> :
   let LGKM_CNT           = ps.LGKM_CNT;
   let MUBUF              = ps.MUBUF;
   let MTBUF              = ps.MTBUF;
+  let Uses               = ps.Uses;
+  let Defs               = ps.Defs;
 
   bits<24> offset;
   bits<8>  vaddr;
diff --git a/llvm/lib/Target/AMDGPU/DSInstructions.td b/llvm/lib/Target/AMDGPU/DSInstructions.td
index f2825c48fceca..19bb4300531cf 100644
--- a/llvm/lib/Target/AMDGPU/DSInstructions.td
+++ b/llvm/lib/Target/AMDGPU/DSInstructions.td
@@ -71,6 +71,8 @@ class DS_Real <DS_Pseudo ps, string opName = ps.Mnemonic> :
   let mayStore           = ps.mayStore;
   let IsAtomicRet        = ps.IsAtomicRet;
   let IsAtomicNoRet      = ps.IsAtomicNoRet;
+  let Uses               = ps.Uses;
+  let Defs               = ps.Defs;
 
   let Constraints = ps.Constraints;
   let DisableEncoding = ps.DisableEncoding;
diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td
index 377d48a48e9b9..154a7401bd6c0 100644
--- a/llvm/lib/Target/AMDGPU/FLATInstructions.td
+++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td
@@ -102,6 +102,8 @@ class FLAT_Real <bits<7> op, FLAT_Pseudo ps, string opName = ps.Mnemonic> :
   let VM_CNT               = ps.VM_CNT;
   let LGKM_CNT             = ps.LGKM_CNT;
   let VALU                 = ps.VALU;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   // encoding fields
   bits<8> vaddr;
@@ -165,6 +167,8 @@ class VFLAT_Real <bits<8> op, FLAT_Pseudo ps, string opName = ps.Mnemonic> :
   let VM_CNT               = ps.VM_CNT;
   let LGKM_CNT             = ps.LGKM_CNT;
   let VALU                 = ps.VALU;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   bits<7> saddr;
   bits<8> vdst;
diff --git a/llvm/lib/Target/AMDGPU/SMInstructions.td b/llvm/lib/Target/AMDGPU/SMInstructions.td
index 40ba47f887710..1f1f86583b233 100644
--- a/llvm/lib/Target/AMDGPU/SMInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SMInstructions.td
@@ -71,6 +71,8 @@ class SM_Real <SM_Pseudo ps, string opName = ps.Mnemonic>
   let AsmMatchConverter    = ps.AsmMatchConverter;
   let IsAtomicRet          = ps.IsAtomicRet;
   let IsAtomicNoRet        = ps.IsAtomicNoRet;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   let TSFlags = ps.TSFlags;
 
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index 394a5ed991bce..aee518680a607 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -65,6 +65,8 @@ class SOP1_Real<bits<8> op, SOP1_Pseudo ps, string real_name = ps.Mnemonic> :
   let isCall             = ps.isCall;
   let isBranch           = ps.isBranch;
   let isBarrier          = ps.isBarrier;
+  let Uses               = ps.Uses;
+  let Defs               = ps.Defs;
 
   // encoding
   bits<7> sdst;
@@ -570,6 +572,8 @@ class SOP2_Real<SOP_Pseudo ps, string name = ps.Mnemonic> :
   let mayStore             = ps.mayStore;
   let Constraints          = ps.Constraints;
   let DisableEncoding      = ps.DisableEncoding;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   // encoding
   bits<7> sdst;
@@ -985,6 +989,8 @@ class SOPK_Real<SOPK_Pseudo ps, string name = ps.Mnemonic> :
   let isTerminator       = ps.isTerminator;
   let isReturn           = ps.isReturn;
   let isBarrier          = ps.isBarrier;
+  let Uses               = ps.Uses;
+  let Defs               = ps.Defs;
 
   // encoding
   bits<7>  sdst;
@@ -1245,6 +1251,8 @@ class SOPC_Real<bits<7> op, SOPC_Pseudo ps> :
   let SchedRW              = ps.SchedRW;
   let mayLoad              = ps.mayLoad;
   let mayStore             = ps.mayStore;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
 
   // encoding
   bits<8> src0;
@@ -1440,6 +1448,8 @@ class SOPP_Real<SOPP_Pseudo ps, string name = ps.Mnemonic> :
   let isCall               = ps.isCall;
   let isBranch             = ps.isBranch;
   let isBarrier            = ps.isBarrier;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
   bits <16> simm16;
 }
 
diff --git a/llvm/lib/Target/AMDGPU/VOPInstructions.td b/llvm/lib/Target/AMDGPU/VOPInstructions.td
index f45ab9bf46db1..5d1573d8dec19 100644
--- a/llvm/lib/Target/AMDGPU/VOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/VOPInstructions.td
@@ -657,6 +657,8 @@ class VOP_SDWA_Real <VOP_SDWA_Pseudo ps> :
   let Constraints          = ps.Constraints;
   let DisableEncoding      = ps.DisableEncoding;
   let TSFlags              = ps.TSFlags;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
   let SchedRW              = ps.SchedRW;
   let mayLoad              = ps.mayLoad;
   let mayStore             = ps.mayStore;
@@ -691,6 +693,8 @@ class Base_VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> :
   let Constraints          = ps.Constraints;
   let DisableEncoding      = ps.DisableEncoding;
   let TSFlags              = ps.TSFlags;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
   let SchedRW              = ps.SchedRW;
   let mayLoad              = ps.mayLoad;
   let mayStore             = ps.mayStore;
@@ -895,6 +899,8 @@ class VOP_DPP_Real <VOP_DPP_Pseudo ps, int EncodingFamily> :
   let Constraints          = ps.Constraints;
   let DisableEncoding      = ps.DisableEncoding;
   let TSFlags              = ps.TSFlags;
+  let Uses                 = ps.Uses;
+  let Defs                 = ps.Defs;
   let SchedRW              = ps.SchedRW;
   let mayLoad              = ps.mayLoad;
   let mayStore             = ps.mayStore;

@jayfoad
Copy link
Contributor

jayfoad commented May 22, 2024

No strong objections from me but a couple of questions:

Is there any in-tree code that relies on implicit operands on Reals? Are there any in-tree tests? What's to stop this bitrotting?

Does this actually change the behaviour of the compiler so that it adds extra operands to Reals in memory (either during codegen or assembly or disassembly)? Or does it jsut change the contents of the MCInstrDesc tables? I am wondering if there is any possible performance impact.

@ritter-x2a
Copy link
Member Author

@jayfoad:

Is there any in-tree code that relies on implicit operands on Reals? Are there any in-tree tests? What's to stop this bitrotting?

I couldn't find any tests in this direction, and no test case needed adjustments for this patch to pass the lit tests.
I would expect llvm-mca to use implicit operands of Reals, but it does not seem to affect any of their AMDGPU tests either.
The llvm-mc tool does not print implicit operands of instructions.

One option I see for testing is to record the implicit operands of all instructions and introduce a test that fails if this changes.
We could for instance collect the implicit operands with the InstrDocsEmitter tablegen backend (which includes implicit operands in the documentation it generates for the instructions).
Changes to the instruction set would require updating this test.

Does this actually change the behaviour of the compiler so that it adds extra operands to Reals in memory (either during codegen or assembly or disassembly)? Or does it jsut change the contents of the MCInstrDesc tables? I am wondering if there is any possible performance impact.

I found only two places where implicit operands are put into additional datastructures:

  • In MachineInstrs, where they are needed for instruction selection. I wouldn't expect real instructions there.
  • In llvm-exegesis, for microbenchmarks. As far as I'm aware, AMDGPU is not supported there (and if it was, correct information about implicit operands would probably be a good thing).

Other than that, the information about implicit operands of MCInsts only lives in the MCInstrDesc table. The getters for implicit operands only return pointers into the table.

@ritter-x2a
Copy link
Member Author

As there hasn't been an update from @jayfoad, the PR does not affect the current testing situation negatively, and since @arsenm approved the PR, I'll merge it as is for now.
Feel free to reach out if you want to discuss introducing testing for implicit instruction operands in a separate PR.

@ritter-x2a ritter-x2a merged commit 0821b79 into llvm:main May 31, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants